package ru.myrtle.umf.tools.ugen.templates;

import java.io.*;
import java.text.*;
import java.util.*;
import ru.myrtle.umf.*;
import ru.myrtle.umf.codegen.*;
import ru.myrtle.umf.codegen.java.*;
import ru.myrtle.umf.tools.ugen.*;

public class UObjectTemplate extends UTemplate
{
    protected final String NL = System.getProperties().getProperty("line.separator");
    protected final String TEXT_1 = "package ";
    protected final String TEXT_2 = ";" + NL + NL;
    protected final String TEXT_3 = NL + "public interface ";
    protected final String TEXT_4 = " ";
    protected final String TEXT_5 = " {" + NL + NL;
    protected final String TEXT_6 = NL + "    public ";
    protected final String TEXT_7 = " ";
    protected final String TEXT_8 = "();" + NL + NL;
    protected final String TEXT_9 = NL + "    public boolean isSet";
    protected final String TEXT_10 = "();" + NL + "    " + NL;
    protected final String TEXT_11 = NL + "    public void set";
    protected final String TEXT_12 = "(";
    protected final String TEXT_13 = " ";
    protected final String TEXT_14 = ");" + NL + NL;
    protected final String TEXT_15 = NL + "    public void unset";
    protected final String TEXT_16 = "();" + NL + NL;
    protected final String TEXT_17 = NL + "    public ";
    protected final String TEXT_18 = " get";
    protected final String TEXT_19 = "();" + NL + NL;
    protected final String TEXT_20 = NL + "    public boolean isSet";
    protected final String TEXT_21 = "();" + NL + NL;
    protected final String TEXT_22 = NL + "    public void set";
    protected final String TEXT_23 = "(";
    protected final String TEXT_24 = " ";
    protected final String TEXT_25 = ");" + NL + NL;
    protected final String TEXT_26 = NL + "    public void unset";
    protected final String TEXT_27 = "();" + NL + NL;
    protected final String TEXT_28 = NL + "    ";
    protected final String TEXT_29 = ";" + NL + "    " + NL;
    protected final String TEXT_30 = "}" + NL;

    /*
     *
     */


    public UObjectTemplate() {

    }

    /*
     *
     */

    public String generate(UTemplateContext context) throws UTemplateRejectException
    {
        final StringBuffer stringBuffer = new StringBuffer();

    checkTemplateObjectType(context, UClass.class);

    UClass object = (UClass) context.getObject();

    String objectName     = UGenUtil.getObjectClassName(object);
    String objectPackage  = UGenUtil.getObjectClassPackage(object);

    context.getResource().setObjectFileName(objectName);
    context.getResource().setObjectFileExtension("java");
    context.getResource().setObjectPackage(objectPackage);

    JavaImportBuilder importBuilder = new JavaImportBuilder();

    createDoc();
    addDocDescription(
            object.getDescription()
    );
    addDocAnnotation("generated");

    StringBuilder extendsList = new StringBuilder();

    if (object.getAllSuperTypes().size() == 0) {
        if (!(objectPackage.equals("ru.myrtle.umf") && objectName.equals("UObject"))) {
            extendsList.append(
                "extends UObject"
            );
            importBuilder.addPackage("ru.myrtle.umf");
        }
    }
    else {
        extendsList.append("extends ");

        for (Iterator<UClass> it = object.getSuperTypes().iterator(); it.hasNext();) {
            UClass parent = it.next();

            extendsList.append(
                parent.getName()
            );

            importBuilder.addPackage(
                UGenUtil.getObjectClassPackage(parent)
            );

            if (it.hasNext()) {
                extendsList.append(", ");
            }
        }
    }

        stringBuffer.append(TEXT_1);
        stringBuffer.append(objectPackage);
        stringBuffer.append(TEXT_2);
        stringBuffer.append(getDocString());
        stringBuffer.append(TEXT_3);
        stringBuffer.append(objectName);
        stringBuffer.append(TEXT_4);
        stringBuffer.append(extendsList.toString());
        stringBuffer.append(TEXT_5);

    for (UFeature feature : object.getFeatures()) {
        if (feature instanceof UAttribute) {
            UAttribute attribute = (UAttribute) feature;

            String attributeName = attribute.getName();
            String attributeType = UGenUtil.getInstanceTypeName(
                attribute, importBuilder
            );

            String varName = "_" + UGenUtil.uncapName(attributeName) + "_";
            String accessorPrefix = UGenUtil.getAccessorPrefix(attribute);

            createDoc("    ");
            addDocDescription(
                    attribute.getDescription()
            );
            addDocAnnotation("generated");

        stringBuffer.append(getDocString());
        stringBuffer.append(TEXT_6);
        stringBuffer.append(attributeType);
        stringBuffer.append(TEXT_7);
        stringBuffer.append(accessorPrefix);
        stringBuffer.append(UGenUtil.capName(attributeName));
        stringBuffer.append(TEXT_8);

            createDoc("    ");
            addDocDescription(
                    attribute.getDescription()
            );
            addDocAnnotation("generated");

        stringBuffer.append(getDocString());
        stringBuffer.append(TEXT_9);
        stringBuffer.append(UGenUtil.capName(attributeName));
        stringBuffer.append(TEXT_10);

            if (attribute.isChangeable()) {
                createDoc("    ");
                addDocDescription(
                        attribute.getDescription()
                );
                addDocAnnotation("generated");


        stringBuffer.append(getDocString());
        stringBuffer.append(TEXT_11);
        stringBuffer.append(UGenUtil.capName(attributeName));
        stringBuffer.append(TEXT_12);
        stringBuffer.append(attributeType);
        stringBuffer.append(TEXT_13);
        stringBuffer.append(varName);
        stringBuffer.append(TEXT_14);

                createDoc("    ");
                addDocDescription(
                        attribute.getDescription()
                );
                addDocAnnotation("generated");

        stringBuffer.append(getDocString());
        stringBuffer.append(TEXT_15);
        stringBuffer.append(UGenUtil.capName(attributeName));
        stringBuffer.append(TEXT_16);

            }
        }
        else if (feature instanceof UReference) {
            UReference reference = (UReference) feature;

            String referenceName = reference.getName();
            String referenceType = UGenUtil.getInstanceTypeName(
                reference, importBuilder
            );

            String varName = "_" + UGenUtil.uncapName(referenceName) + "_";

            createDoc("    ");
            addDocDescription(
                reference.getDescription()
            );
            addDocAnnotation("generated");

        stringBuffer.append(getDocString());
        stringBuffer.append(TEXT_17);
        stringBuffer.append(referenceType);
        stringBuffer.append(TEXT_18);
        stringBuffer.append(UGenUtil.capName(referenceName));
        stringBuffer.append(TEXT_19);

            createDoc("    ");
            addDocDescription(
                reference.getDescription()
            );
            addDocAnnotation("generated");

        stringBuffer.append(getDocString());
        stringBuffer.append(TEXT_20);
        stringBuffer.append(UGenUtil.capName(referenceName));
        stringBuffer.append(TEXT_21);

            if (reference.isChangeable()) {
                createDoc("    ");
                addDocDescription(
                    reference.getDescription()
                );
                addDocAnnotation("generated");

        stringBuffer.append(getDocString());
        stringBuffer.append(TEXT_22);
        stringBuffer.append(UGenUtil.capName(referenceName));
        stringBuffer.append(TEXT_23);
        stringBuffer.append(referenceType);
        stringBuffer.append(TEXT_24);
        stringBuffer.append(varName);
        stringBuffer.append(TEXT_25);

                createDoc("    ");
                addDocDescription(
                    reference.getDescription()
                );
                addDocAnnotation("generated");

        stringBuffer.append(getDocString());
        stringBuffer.append(TEXT_26);
        stringBuffer.append(UGenUtil.capName(referenceName));
        stringBuffer.append(TEXT_27);

            }
	    }
    }

    for (UOperation operation : object.getOperations()) {
        String signature = UGenUtil.createOperationSignature(
                operation, importBuilder, false, false, "", "public"
        );

        createDoc("    ");
        addDocDescription(
            operation.getDescription()
        );
        addDocAnnotation("generated");

        stringBuffer.append(getDocString());
        stringBuffer.append(TEXT_28);
        stringBuffer.append(signature);
        stringBuffer.append(TEXT_29);

    }

        stringBuffer.append(TEXT_30);

    insertImport(stringBuffer, importBuilder, objectPackage);


        return stringBuffer.toString();
    }

    // ---------------------------------------------------------------------------------------
    // ---------------------------------------------------------------------------------------

}
